home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 February
/
EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso
/
enigma
/
earcd
/
comm
/
comm2
/
ctsrc701.lha
/
callstat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-01
|
27KB
|
697 lines
/*
Hue: This is the source of the current version of callstat. I've been
running it on my system for some time, and it seems to be stable.
Unfortunately, one of the other Swarm Sysops, who has a hard-drive-
based STadel node, has reported that this version of callstat acts
very strangely with his system. I haven't yet figured where the
problem is...
In any case, the basic logic is sound, and fairly straightforward.
The program is undocumented as yet; I haven't reached the point
where I'm ready to release it to the public, and I never document
my own code...until it's too late. :-) Anyway, I don't expect
you'll have much trouble figuring things out. The only problem
areas are in the Cit-specific stuff, such as access to ctdltabl.sys
and calllog.sys.
Any comments, questions, complaints, or speeches would be welcomed,
unless they deal with my personal programming style. :-)
--Royce, 13Mar88, far too late in the evening...
*/
#define BOOLEAN int
#define CITADEL86 1
/* #define ATARI_ST 1 */
#include "ctdl.h" /* header file */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <pragmas/dos_pragmas.h>
#include "exec/memory.h"
#include "exec/ports.h"
#include "exec/exec.h"
#ifdef ATARI_ST
#include <osbind.h>
#include "audit.h"
extern struct config cfg;
#endif
#ifdef CITADEL86
#define safeopen fopen
#define Cconin() getchar()
#define Fdelete unlink
#define doExit exit
typedef char pathSpec[200];
extern CONFIG cfg;
void get_data(void);
void munch(void);
void write_data(void);
void write_stat_file(void);
void UpdateBar(void);
long baud_code(long baud);
void file_error(char *file, char *access);
BOOLEAN find_on(void);
char get_stuff(void);
void write_a_stat(char *desc, char stat);
void write_hist_bar(unsigned stat, float factor);
#endif
struct {
unsigned hour,min;
} on,off,last;
BOOLEAN newuser,termstay,disconnect,preempt,timeout,evile,nosysop,update,docb,
debug, barupdate, SysUp = FALSE;
char ch,date[20],str[20];
long baud;
unsigned long dur;
FILE *safeopen(),*fp;
pathSpec fnlog = "",fndat,fnstat,fncallbaud;
long total,calls[24],durations[20],callbaud[24][9],
nnewusers,ntermstays,ndisconnects,nnewdiscons,npreempts,
ntimeouts,neviles;
long bauds[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
long totalduration,totalidle, netcount;
long baudduration[9] = { 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l};
char bartitle[100] = "";
int main(int , char **);
int main(argc,argv)
int argc;
char *argv[];
{
cfg.weAre = UTILITY;
printf("Citadel Caller Log Statistics Report, %s\n", VERSION_NAME);
printf("Do a 'callstat -?' for help.\n");
nosysop = FALSE;
update = FALSE;
docb = FALSE;
debug = FALSE;
while (argc > 1) {
--argc;
++argv;
#ifndef CITADEL86
if (strcmp(*argv, "-c") == 0)
docb = TRUE;
if (strcmp(*argv, "-d") == 0)
debug = TRUE;
if (strcmp(*argv, "-s") == 0)
nosysop = TRUE;
if (strcmp(*argv, "-u") == 0)
update = TRUE;
if (strcmp(*argv, "-?") == 0) {
printf("usage: callstat [-c] [-s] [-u]\n");
printf(" -c writes callbaud.sys\n");
printf(" -s turns off sysConsole stats\n");
printf(" -u deletes calllog.sys & updates calldata.sys\n");
doExit(0);
}
#else
if (strcmp(*argv, "-c") == 0)
docb = TRUE;
else if (strcmp(*argv, "-d") == 0)
debug = TRUE;
else if (strcmp(*argv, "-s") == 0)
nosysop = TRUE;
else if (strcmp(*argv, "-u") == 0)
update = TRUE;
else if (strncmp(*argv, "-b", 2) == 0) {
barupdate = TRUE;
if (strlen(*argv) > 2)
strcpy(bartitle, *argv + 2);
}
else if (strcmp(*argv, "-?") == 0) {
printf("usage: callstat [-c] [-s] [-u] [filename]\n");
printf(" -c writes callbaud.sys\n");
printf(" -s turns off sysConsole stats\n");
printf(" -u deletes calllog.sys & updates calldata.sys\n");
printf(" -b[title name] updates bar.sys\n");
printf(" \"filename\" analyze this file, instead\n");
doExit(0);
}
else if (**argv != '-') {
strcpy(fnlog, *argv);
}
#endif
}
#ifdef ATARI_ST
if (!readSysTab(FALSE))
#endif
#ifdef CITADEL86
if (!readSysTab(FALSE, TRUE))
#endif
doExit(1);
#ifdef ATARI_ST
if (((cfg.call_log & aEXIT) == 0) || ((cfg.call_log & aLOGIN) == 0) ||
((cfg.call_log & aDNLOAD == 1))) {
printf("Sorry, but callstat currently needs system ups & downs\n");
printf("and user logins to be recorded, and file transfers to\n");
printf("be unrecorded.\n");
doExit(1);
}
#endif
#ifdef ATARI_ST
if (strlen(fnlog) == 0)
sprintf(fnlog,"%s\\CALLLOG.SYS",&cfg.codeBuf[cfg.auditDir]);
sprintf(fndat,"%s\\CALLDATA.SYS",&cfg.codeBuf[cfg.sysDir]);
sprintf(fnstat,"%s\\CALLSTAT.SYS",&cfg.codeBuf[cfg.auditDir]);
sprintf(fncallbaud,"%s\\CALLBAUD.SYS",&cfg.codeBuf[cfg.auditDir]);
#endif
#ifdef CITADEL86
if (strlen(fnlog) == 0)
makeSysName(fnlog, "calllog.sys", &cfg.auditArea);
makeSysName(fndat, "calldata.sys", &cfg.auditArea);
makeSysName(fnstat, "callstat.sys", &cfg.auditArea);
makeSysName(fncallbaud, "callbaud.sys", &cfg.auditArea);
#endif
last.hour = 100;
get_data();
munch();
if (update) {
Fdelete(fnlog);
write_data();
}
#ifdef CITADEL86
if (barupdate) {
UpdateBar();
}
#endif
write_stat_file();
return 0;
}
void file_error(char *file, char *access)
{
printf("Can't open %s for %s!\n",file,access);
printf("Hit return: "); /* For people running under GEM desktop. */
ch = Cconin();
printf("\n");
}
void get_data()
{
unsigned i,j;
if ((fp = safeopen(fndat,"r")) == NULL) {
date[0] = NULL;
total = 0;
zero_struct(calls);
zero_struct(durations);
totalduration = 0;
totalidle = 0;
zero_struct(bauds);
zero_struct(callbaud);
nnewusers = 0;
ntermstays = 0;
ndisconnects = 0;
nnewdiscons = 0;
npreempts = 0;
ntimeouts = 0;
neviles = 0;
}
else {
printf("Reading cumulative data...\n");
fscanf(fp,"%s\n",date);
fscanf(fp,"%d\n",&total);
for (i = 0; i <= 23; i++)
fscanf(fp,"%d\n",&calls[i]);
for (i = 0; i <= 19; i++)
fscanf(fp,"%d\n",&durations[i]);
fscanf(fp,"%ld\n",&totalduration);
fscanf(fp,"%ld\n",&totalidle);
for (i = 0; i <= 8; i++)
fscanf(fp,"%d\n",&bauds[i]);
for (i = 0; i <= 23; i++)
for (j = 0; j <= 8; j++)
fscanf(fp,"%d\n",&callbaud[i][j]);
fscanf(fp,"%d\n",&nnewusers);
fscanf(fp,"%d\n",&ntermstays);
fscanf(fp,"%d\n",&ndisconnects);
fscanf(fp,"%d\n",&nnewdiscons);
fscanf(fp,"%d\n",&npreempts);
fscanf(fp,"%d\n",&ntimeouts);
fscanf(fp,"%d\n",&neviles);
fclose(fp);
}
}
long baud_code(long baud)
{
if (baud == 300) return 1;
else if (baud == 1200) return 2;
else if (baud == 2400) return 3;
else if (baud == 4800) return 4;
else if (baud == 9600) return 5;
else if (baud == 14400) return 6;
else if (baud == 19200) return 7;
else if (baud >= 38400) return 8;
else return 0;
}
char isnet;
BOOLEAN find_on() /* Scan for next user login time. */
{
int rc;
char up, buffer[800];
buffer[0] = 0;
do {
str[0] = NULL;
rc = fscanf(fp,"%s ",str);
if (debug)
printf("-%s-",str);
if (strcmp(str, "up") == 0)
up = TRUE;
/* Next if handles system down/up. */
strcat(buffer, str);
if ((rc == 1) && (str[0] == '@')) {
if (debug)
printf("\n");
if (last.hour != 100) {
if (SysUp && up) { /* damaged calllog */
fscanf(fp,"%d:",&last.hour);
fscanf(fp,"%d\n",&last.min);
on.hour = 100;
}
else {
fscanf(fp,"%d:",&on.hour);
fscanf(fp,"%d\n",&on.min);
}
}
else {
fscanf(fp,"%d:",&last.hour);
fscanf(fp,"%d\n",&last.min);
on.hour = 100;
}
if (on.hour != 100) {
if (last.hour > on.hour)
on.hour += 24;
dur = ((on.hour * 60 + on.min) -
(last.hour * 60 + last.min));
/*printf("\n1: adding %d\n", dur);*/
totalidle += dur;
last.hour = 100;
}
up = FALSE;
}
} while (strcmp(str, "mode:") && (rc != EOF) && ((str[0] != ':') || (str[1] != NULL)));
if (debug)
printf("buffer is -%s-", buffer);
/*
Bug: Normally, the only time the substring " : " shows up in the
calllog, is between a userID and the date of the login. Thus
the previous while loop scans for words (i.e. a sequence of
characters terminated by white-space), and terminates when it
finds the word ": ". Normally, this means that the date and
time of signon are to immediately follow.
However, if some userID contains the substring " : " (or ": "
at the start), callstat will rapidly go to heg. More
stringent error-checking is needed to guard against this
(e.g., check to make sure that something of the form ddCccdd
follows the current instance of ": ", where d is a digit and
C/c is a character)...
*/
if (debug)
printf("\n");
if (rc == EOF)
return FALSE;
else {
SysUp = TRUE;
fscanf(fp,"%s ",str); /* Skip the date */
if (date[0] == NULL) /* Record it if needed (first time) */
strcpy(date,str);
isnet = (strcmp(buffer, "Systeminnetworkmode:") == 0);
return TRUE;
}
}
char get_stuff()
{
int rc;
fscanf(fp,"%d:",&on.hour);
fscanf(fp,"%d - ",&on.min);
rc = fscanf(fp,"%d:",&off.hour);
if (rc != 1) {
printf("\nYuck! Your calllog.sys file is corrupted!\n");
printf("(A user is recorded as logging in, but not out.)\n");
printf("Please use an editor to fix things before rerunning.\n");
fclose(fp);
doExit(1);
}
fscanf(fp, (isnet) ? "%d" : "%d (", &off.min);
if (!isnet) {
rc = fscanf(fp,"%d)",&baud);
if (rc == 0) { /* Login was at sysConsole */
baud = 0;
fscanf(fp,"%s)",str);
}
baud = baud_code(baud);
}
else baud = 0;
newuser = FALSE;
termstay = FALSE;
disconnect = FALSE;
preempt = FALSE;
timeout = FALSE;
evile = FALSE;
do {
ch = getc(fp);
switch (ch) {
case '+' :
newuser = TRUE;
break;
case '-' :
termstay = TRUE;
break;
case 'd' :
disconnect = TRUE;
break;
case 'p' :
preempt = TRUE;
break;
case 't' :
timeout = TRUE;
break;
case 'E' :
evile = TRUE;
default :
break;
}
} while (ch != '\n');
return isnet;
}
void munch()
{
char net;
if ((fp = safeopen(fnlog,"r")) == NULL) {
file_error("calllog.sys","input");
return;
}
printf("Munching...\n");
while (find_on()) {
net = get_stuff();
if (!net) total++;
printf("\r%d",total);
if (!net) calls[on.hour]++;
if (last.hour > on.hour)
on.hour += 24;
dur=((on.hour*60+on.min)-(last.hour*60+last.min));
/*printf("\n2: adding %ld (Last was %d:%02d, now is %d:%02d)\n", dur, last.hour, last.min, on.hour, on.min);*/
totalidle += dur;
if (on.hour >= 24)
on.hour -= 24;
last.hour = off.hour;
last.min = off.min;
if (on.hour > off.hour)
off.hour += 24;
dur=((off.hour*60+off.min) - (on.hour * 60 + on.min));
if (!net) {
totalduration += dur;
baudduration[baud] += dur;
}
else netcount++;
dur /= 15;
if (dur > 19)
dur = 19;
if (!net) {
durations[dur]++;
bauds[baud]++;
callbaud[on.hour][baud]++;
if (newuser)
nnewusers++;
if (termstay)
ntermstays++;
if (disconnect) {
ndisconnects++;
if (newuser)
nnewdiscons++;
}
if (preempt)
npreempts++;
if (timeout)
ntimeouts++;
if (evile)
neviles++;
}
}
fclose(fp);
printf("\n");
}
void write_data()
{
unsigned i,j;
if ((fp = safeopen(fndat,"w")) == NULL)
file_error("calldata.sys","output");
else {
printf("Writing cumulative data...\n");
fprintf(fp,"%s\n",date);
fprintf(fp,"%d\n",total);
for (i = 0; i <= 23; i++)
fprintf(fp,"%d\n",calls[i]);
for (i = 0; i <= 19; i++)
fprintf(fp,"%d\n",durations[i]);
fprintf(fp,"%ld\n",totalduration);
fprintf(fp,"%ld\n",totalidle);
for (i = 0; i <= 8; i++)
fprintf(fp,"%d\n",bauds[i]);
for (i = 0; i <= 23; i++)
for (j = 0; j <= 8; j++)
fprintf(fp,"%d\n",callbaud[i][j]);
fprintf(fp,"%d\n",nnewusers);
fprintf(fp,"%d\n",ntermstays);
fprintf(fp,"%d\n",ndisconnects);
fprintf(fp,"%d\n",nnewdiscons);
fprintf(fp,"%d\n",npreempts);
fprintf(fp,"%d\n",ntimeouts);
fprintf(fp,"%d\n",neviles);
fclose(fp);
}
}
void write_hist_bar(unsigned stat, float factor)
{
unsigned i;
fprintf(fp,": ");
if ((stat / factor) >= 1.0)
for (i = 1; i <= (int) (stat / factor); i++)
fprintf(fp,"*");
else if (stat >= 1)
fprintf(fp,"*");
fprintf(fp," (%d)\n", stat);
fflush(fp);
}
void write_a_stat(char *desc, char stat)
{
#ifndef CITADEL86
fprintf(fp,"%s: %d (%d%%)\n",desc,stat,stat * 100 / total);
#else
fprintf(fp, "%-30s%-15d%d\n", desc, stat, stat * 100 / total);
#endif
}
void write_stat_file()
{
unsigned i,j,max;
float factor;
Fdelete(fnstat);
if ((fp = safeopen(fnstat,"w")) == NULL)
file_error("callstat.sys","output");
else {
printf("Writing stat file...\n");
fprintf(fp,"\n The Antithesystem Memorial RT Histogram.\n\n");
fprintf(fp," The following statistics have been collected since %s.\n\n",date);
fprintf(fp," Total number of calls represented: %d\n\n",total);
max = 25;
for (i = 0; i <= 23; i++)
if (calls[i] > max)
max = calls[i];
factor = max / 25.0;
fprintf(fp," Usage histogram (each number represents an hour of the day, each '*'\n");
fprintf(fp,"represents about %d calls at that hour):\n",(int) factor);
for (i = 0; i <= 23; i++) {
fprintf(fp,"%3d",i);
write_hist_bar(calls[i],factor);
}
fprintf(fp,"\n");
max = 25;
for (i = 0; i <= 19; i++)
if (durations[i] > max)
max = durations[i];
factor = max / 25.0;
fprintf(fp," Call duration histogram (each number represents a call duration of at\n");
fprintf(fp,"most that much time, each '*' represents about %d calls of that duration):\n",(int) factor);
for (i = 0; i <= 19; i++) {
fprintf(fp,"%2d:%d",(i + 1) * 15 / 60,(i + 1) * 15 % 60);
if (i % 4 == 3)
fprintf(fp,"0");
write_hist_bar(durations[i],factor);
}
fprintf(fp," The average call duration is about %ld minutes.\n",totalduration / total);
fprintf(fp," The average idle time before/after a call is about %ld minutes.\n\n",totalidle / total);
max = 25;
for (i = 0; i <= 8; i++)
if (bauds[i] > max)
max = bauds[i];
factor = max / 25.0;
fprintf(fp," Baud rate histogram (each number represents a baud rate, each '*' represents\n");
fprintf(fp,"about %d calls at that baud rate):\n",(int) factor);
for (i = 0 + nosysop; i <= cfg.sysBaud + 1; i++) {
switch (i) {
case 0 : fprintf(fp," sys"); break;
case 1 : fprintf(fp," 300"); break;
case 2 : fprintf(fp," 1200"); break;
case 3 : fprintf(fp," 2400"); break;
case 4 : fprintf(fp," 4800"); break;
case 5 : fprintf(fp," 9600"); break;
case 6 : fprintf(fp,"14400"); break;
case 7 : fprintf(fp,"19200"); break;
case 8 : fprintf(fp,"38400"); break;
}
write_hist_bar(bauds[i],factor);
}
fprintf(fp,"\n");
fprintf(fp, "There were %ld network sessions.\n\n", netcount);
#ifndef CITADEL86
write_a_stat(" Number of new users",nnewusers);
write_a_stat(" Number of uses of .T(erminate) S(tay)",ntermstays);
write_a_stat(" Number of disconnects",ndisconnects);
write_a_stat(" Number of new user disconnects",nnewdiscons);
write_a_stat(" Number of preemptions",npreempts);
write_a_stat(" Number of time-outs",ntimeouts);
write_a_stat(" Number of EVILE users",neviles);
#else
fprintf(fp, "%-25s%-15s%s\n", " Description",
"Total Number", "Percentage");
fprintf(fp, "%-25s%-15s%s\n", " -----------",
"------------", "----------");
write_a_stat(" New users", nnewusers);
write_a_stat(" .T(erminate) S(tay) usage", ntermstays);
write_a_stat(" Disconnects", ndisconnects);
write_a_stat(" New user disconnects", nnewdiscons);
write_a_stat(" Preemptions", npreempts);
write_a_stat(" Time-outs", ntimeouts);
write_a_stat(" EVILE users", neviles);
#endif
fclose(fp);
}
if (docb != TRUE)
return;
Fdelete(fncallbaud);
if ((fp = safeopen(fncallbaud,"w")) == NULL)
file_error("callbaud.sys","output");
else {
printf("Writing call/baud file...\n");
fprintf(fp,"\n");
fprintf(fp," The following statistics have been collected since %s.\n\n",date);
fprintf(fp," Total number of calls represented: %d\n\n",total);
max = 25;
for (i = 0; i <= 23; i++)
for (j = 0; j <= 8; j++)
if (callbaud[i][j] > max)
max = callbaud[i][j];
factor = max / 25.0;
fprintf(fp," Usage/baud rate histogram (each pair of numbers represents an hour of the\n");
fprintf(fp,"day and a baud rate, each '*' represents about %d calls at that hour and\n",(int) factor);
fprintf(fp,"baud rate):\n");
for (i = 0; i <= 23; i++)
for (j = 0 + nosysop; j <= cfg.sysBaud + 1; j++) {
fprintf(fp,"%3d,",i);
switch (j) {
case 0 : fprintf(fp," sys"); break;
case 1 : fprintf(fp," 300"); break;
case 2 : fprintf(fp," 1200"); break;
case 3 : fprintf(fp," 2400"); break;
case 4 : fprintf(fp," 4800"); break;
case 5 : fprintf(fp," 9600"); break;
case 6 : fprintf(fp,"14400"); break;
case 7 : fprintf(fp,"19200"); break;
case 8 : fprintf(fp,"38400"); break;
}
write_hist_bar(callbaud[i][j],factor);
}
fclose(fp);
}
}
void crashout(str)
char *str;
{
puts(str);
doExit(1);
}
/*
* Note Royce doesn't support 4800, so we must force in a 0.
*/
void UpdateBar()
{
FILE *fd, *fopen();
extern char *APPEND_TEXT;
if ((fd = fopen("bar.sys", APPEND_TEXT)) != NULL) {
if (strlen(bartitle) == 0) {
printf("Title for this data: ");
gets(bartitle);
}
fprintf(fd, "%s\n", bartitle);
fprintf(fd, "%d\n", bauds[0]);
fprintf(fd, "%ld\n", baudduration[0]);
fprintf(fd, "%d\n", bauds[1]);
fprintf(fd, "%ld\n", baudduration[1]);
fprintf(fd, "%d\n", bauds[2]);
fprintf(fd, "%ld\n", baudduration[2]);
fprintf(fd, "%d\n", bauds[3]);
fprintf(fd, "%ld\n", baudduration[3]);
fprintf(fd, "%d\n", bauds[4]);
fprintf(fd, "%ld\n", baudduration[4]);
fprintf(fd, "%d\n", bauds[5]);
fprintf(fd, "%ld\n", baudduration[5]);
fprintf(fd, "%d\n", bauds[6]);
fprintf(fd, "%ld\n", baudduration[6]);
fprintf(fd, "%d\n", bauds[7]);
fprintf(fd, "%ld\n", baudduration[7]);
fprintf(fd, "%d\n", bauds[8]);
fprintf(fd, "%ld\n", baudduration[8]);
fprintf(fd, "%d\n", 0);
fprintf(fd, "0\n");
fprintf(fd, "%d\n", bauds[8]);
fprintf(fd, "%ld\n", baudduration[8]);
fprintf(fd, "%ld\n", totalduration);
fprintf(fd, "%ld\n", totalidle);
fprintf(fd, "%d\n", nnewusers);
fprintf(fd, "\n");
fclose(fd);
}
}